#!/usr/bin/python3
# -*- coding:utf-8 -*-
import re

from qturboframe.lib.report.log import logger
from qturboframe.lib.utils.by import By
from qturboframe.lib.webdriver.exceptions import SeleniumError
from qturboframe.public_ui.h_ui.select_table import SelectTable as HuiSelectTable
from selenium.webdriver import ActionChains
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


class SelectTable(HuiSelectTable):
    """
    重写hui的下拉多选择器操作
    """

    def set_value_for_single(self, value, timeout=20):
        """
        hui单选下拉选择器框选择

        :Args:
         - value: 选择项的文本
         - timeout: 超时时间，默认是20s

        :Example:
         - 例1: select.set_value_for_single('苹果')
         - 例2: select.set_value_for_single('苹果',timeout=5)
        """
        select_element = self._element.find_element_by_attribute(
            'css selector', 'div.h-selectTable-selection')
        select_element.secure_click()
        dropdown_div = self._element.exist(
            'css selector', 'div.h-select-dropdown', timeout=0.1)
        if not dropdown_div:
            dropdown_div = self._driver.find_element_by_attribute(
                'xpath', "//body/div[contains(@class,'h-select-dropdown') and not(contains(@style,'display: none'))]",
                timeout=self.timeout)
        # 检查存在搜索输入框
        input_element = dropdown_div.exist(
            'css selector', 'div.h-selectTable-dropdown-noline-content>span.h-selectTable-search>input', timeout=0.5)
        if input_element:
            input_element.send_keys(value)
        # 显性等待，直到用户名控件加载出来才进行下一步
        waitFlag = WebDriverWait(self._driver, timeout, 0.5).until(
            EC.presence_of_element_located(
                (By.XPATH, '//div[@class="h-selectTable-dropdown-list"]/div/ul/li')))
        if waitFlag:
            div_list = dropdown_div.find_element_by_attribute(By.XPATH, './/div[@id="blockWrapper"]')
            # 将页面滚动到 顶部
            action = ActionChains(driver=self._driver)
            action.move_to_element(div_list).perform()
            fundFlag = False
            index = 0
            while index < 10:
                action.key_down(Keys.CONTROL).send_keys(Keys.HOME).key_up(Keys.CONTROL).perform()
                liEleXpath = f'//ul/li/span[contains(text(), "{value}")]'
                selectLists = div_list.find_elements_by_attribute(By.XPATH, liEleXpath, timeout=1)
                if len(selectLists) > 0:
                    for ele in selectLists:
                        if ele.is_displayed():
                            ele.click()         # 模糊匹配会匹配到多的，所以需要去点击当前下拉框可见的
                            fundFlag = True
                            break
                    if fundFlag:
                        break
                else:
                    action.send_keys(Keys.PAGE_DOWN * 5)
                    action.perform()
                    index += 1
                    logger.warning(f"No.{index}：当前页没有找到待勾选的元素：{value}，向下滚动")
            if not fundFlag:
                logger.error(f"下翻查找 {index} 次，仍然没有找到待勾选的元素：{value}")
                raise SeleniumError(f"下翻查找 {index} 次，仍然没有找到待勾选的元素：{value}")
        else:
            logger.error("下拉元素尚未加载！")

    def set_value_for_multiple(self, values: list, timeout=10):
        """
        hui单选下拉选择器框选择

        :Args:
         - value: 选择项的文本
         - timeout: 超时时间，默认是20s
        """
        _checked_label_status = "h-checkbox-wrapper-checked"
        # 先全部清空
        self.clear_for_multiple()
        # 打开下拉框
        selectInput = self._element.find_element_by_attribute('css selector', 'div.h-selectTable-selection')
        try:
            # 当元素被覆盖，则无法点击
            selectInput.click()
        except Exception as e:
            self._driver.execute_script("arguments[0].click();", selectInput)
        dropdown_div = self._element.exist(
            'css selector', 'div.h-select-dropdown', timeout=0.1)
        if not dropdown_div:
            dropdown_div = self._element.find_element_by_attribute(
                'xpath', "//body/div[contains(@class,'h-select-dropdown') and not(contains(@style,'display: none'))]",
                timeout=self.timeout)
        # 输入框
        inputElement = dropdown_div.exist(
            'css selector', 'div.h-selectTable-dropdown-noline-content>span.h-selectTable-search>input', timeout=0.1)
        if values[0] in ["全选", "全不选", "all", "notAll"]:
            buttonName = values[0]
            buttonName = "全选" if buttonName == "all" else buttonName
            buttonName = "全不选" if buttonName == "notAll" else buttonName
            allButton = dropdown_div.find_element_by_attribute(
                'css selector', 'div.h-select-checkall>button>span', f'text:{buttonName}', timeout=3)
            allButton.click()
        else:
            div_list = dropdown_div.find_elements_by_attribute(By.XPATH, './/div[@id="blockWrapper"]', timeout=0.5)
            if div_list:
                # 将页面滚动到 顶部  ---- 反洗钱的表格下拉框 2025-04-11 修改
                action = ActionChains(driver=self._driver)
                action.move_to_element(div_list[0]).perform()
                for value in values:
                    value = value.strip()
                    if inputElement:
                        inputElement.send_keys(value)
                    else:
                        action.key_down(Keys.CONTROL).send_keys(Keys.HOME).key_up(Keys.CONTROL).perform()
                    try:
                        fundFlag = False
                        index = 0
                        while index < 10:
                            selectLists = dropdown_div.find_elements_by_attribute(
                                'xpath',
                                f'//div[@class="h-selectTable-dropdown-list"]/div/ul/li/span[contains(text(),"{value}")]',
                                timeout=2)
                            if len(selectLists) > 0:
                                for ele in selectLists:
                                    # logger.debug(f'ele text :{ele.text}')
                                    if ele.is_displayed() and re.search(value, ele.text, re.I):
                                        labelEle = ele.find_element_by_attribute(By.XPATH, './label')
                                        labelEleClass = labelEle.get_attribute('class')
                                        if _checked_label_status in labelEleClass:
                                            logger.info(f"元素：{value} 已被选中！")
                                        else:
                                            ele.secure_click(0.5)
                                            logger.info(f"勾选元素：{value}")
                                        fundFlag = True
                                        break
                                if fundFlag:
                                    break
                                else:
                                    action.send_keys(Keys.PAGE_DOWN * 10).perform()
                                    index += 1
                            else:
                                action.send_keys(Keys.PAGE_DOWN * 8).perform()
                                index += 1
                                logger.warning(f"No.{index}：当前页没有找到待勾选的元素：{value}，向下滚动")
                        if not fundFlag:
                            logger.error(f"下翻查找 {index} 次，仍然没有找到待勾选的元素：{value}")
                            raise SeleniumError(f"下翻查找 {index} 次，仍然没有找到待勾选的元素：{value}")
                    except Exception as e:
                        trLists = dropdown_div.find_elements_by_attribute(
                            'xpath',
                            f'//div[@class="h-selectTable-dropdown-list"]//div[@class="h-table-body"]/'
                            f'table/tbody/tr/td/div/span[contains(text(),"{value}")]',
                            timeout=1)
                        if len(trLists) > 0:
                            trLists[0].secure_click()
                            logger.info(f"勾选元素：{value}")
                        else:
                            logger.error(f"没有找到待勾选的元素：{value}")
                            raise SeleniumError(f"没有找到待勾选的元素：{value}")
                        # logger.error("下拉元素尚未加载！")
            else:
                # 兼容 合规的下拉表格类型 2025-04-11 修改
                for value in values:
                    value = value.strip()
                    if inputElement:
                        inputElement.clear()
                        inputElement.send_keys(value)
                        row_xpath = f'//tbody[@class="h-table-tbody"]/tr/td/div/span[contains(text(),"{value}")]'
                        target_cell = dropdown_div.find_element_by_attribute(By.XPATH, row_xpath, timeout=0.5)
                        target_cell.click()
                        logger.info(f"勾选元素：{value}")
                    else:
                        logger.warning(f"没有找到输入框！暂不支持的操作！")
                selectInput.secure_click()
        # selectInput.secure_click()    # 关闭下拉框移动到外层去处理！

    def clear_for_multiple(self):
        """
        hui单选下拉框清除选项值

        :Example:
         - 例: select.clear_for_single()
        """
        data_divs = self._element.find_elements_by_attribute(
            'css selector', 'div.h-select-selection>div.h-tag', timeout=1)
        if len(data_divs) > 0:
            data_divs[0].find_element_by_attribute(
                'css selector', 'i.h-icon-close', timeout=self.timeout).secure_click()
            self.clear_for_multiple()

    def is_default_for_multiple(self, value: list):
        """
        检查hui单选下拉框默认值

        :Args:
         - value: 待检查的选项值

        :Returns:
            匹配返回True，否则返回False

        :Example:
         - 例: select.is_default_for_single('香蕉')
        """
        span_value = self._element.find_element_by_attribute(
            By.XPATH, '//div[@class="h-selectTable-selection"]', timeout=0.1)
        text = span_value.title
        if text:
            textList = text.split(",")
            for unit in textList:
                if unit not in value:
                    logger.error('默认值不匹配！')
                    return False
            else:
                return True
        else:
            logger.error(f'没有找到默认值组件框！')
            return False

    def is_nonnull(self):
        '''
        检查hui下拉框是否有非空属性

        :Returns:
            非空返回True，否则返回False

        :Example:
         - 例: select.is_nonnull()
        '''
        self._element.focus()
        form_item = self._element.find_element_by_attribute(
            'xpath', './ancestor::div[contains(@class, "h-form-item-content")]/'
                     'parent::div[contains(@class, "h-form-item")]', timeout=self.timeout)
        item_class_list = form_item.get_attribute('class').split(' ')
        if 'h-form-item-required' in item_class_list:
            return True
        else:
            return False

    def check_default_for_multiple(self, value):
        """
        检查hui单选下拉框默认值

        :Args:
         - value: 待检查的选项值

        :Raises:
            SeleniumError: 下拉框的默认值校验不通过

        :Example:
         -例: select.check_default_for_single('香蕉')
        """
        if not self.is_default_for_multiple(value):
            raise SeleniumError('下拉框的默认值校验不通过！')

    def check_nonnull(self):
        '''
        检查hui下拉框是否有非空属性

        :Raises:
            SeleniumError: 下拉框的非空校验不通过

        :Example:
         - 例: select.check_nonnull()
        '''
        if not self.is_nonnull():
            raise SeleniumError('下拉框的非空校验不通过！')

    def check_down_list(self, keys_list: list):
        '''
        检查hui下拉框 枚举值

        :Raises:
            SeleniumError: 下拉框的非空校验不通过

        :Example:
         - 例: select.check_nonnull()
        '''
        select_element = self._element.find_element_by_attribute(
            'css selector', 'div.h-selectTable-selection')
        select_element.secure_click()
        dropdown_div = self._element.exist('css selector', 'div.h-select-dropdown', timeout=0.1)
        list_xpath = f'//ul/li/span'
        # 将页面滚动到 顶部
        action = ActionChains(driver=self._driver)
        action.move_to_element(dropdown_div).perform()
        select_list_keys = list()
        index = 0
        while index < 5:
            select_list = dropdown_div.find_elements_by_attribute(By.XPATH, list_xpath, timeout=1)
            for unit in select_list:
                text = unit.text.strip()
                if text:
                    select_list_keys.append(text)
            action.send_keys(Keys.ARROW_DOWN * 5).perform()
            index += 1
        select_list_keys = list(set(select_list_keys))
        logger.info(f"下拉列表值：{select_list_keys}")
        for unit in keys_list:
            flag = False
            for raw in select_list_keys:
                if not raw:
                    continue
                if re.search(unit, raw, re.I):
                    logger.info(f"{unit} 在下拉列表中存在")
                    flag = True
                    break
            if not flag:
                error = f"{unit} 在下拉列表{select_list_keys}中不存在！"
                logger.error(error)
                raise SeleniumError(error)


